package Logik;

import Interfaces.Medienverwaltung;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
import java.util.Iterator;
import GUI.*;

/**
 * Implementiert das Interface und beinhaltet zwei weitere Methoden zum Laden
 * und zum Speichern der Medienliste.
 *
 * @author Andreas Konsek
 * @param mdl - Liste der Medien
 * @param f - Datei in welche die Medienliste gespeichert wird.
 */
public class Medienquelle implements Medienverwaltung, Serializable {

    private List<Medium> mdl = new ArrayList<Medium>();
    File f = new File("src/Logik/Medienliste.md");
    
    /**
     * Überprüft ob Medium bereits in Liste vorhanden. Falls nein wird es der
     * Liste hinzugefügt, sonst Fehlermeldung. Abschließend wird die Liste
     * wieder in die Datei geschrieben.
     *
     * @param it - Lokaler Iterator für die Listen
     * @param m - Anzulegendes Medium
     * @param mdl - Medienliste
     * @throws IOException, ClassNotFoundException
     */
    @Override
    public void anlegen(Medium m) {
        if (f.exists()) {
            ListeLaden();

            Iterator<Medium> it = mdl.iterator();

            while (it.hasNext()) {
                Medium cmp = it.next();
                if (cmp.getArtikelnr() == m.getArtikelnr()) {
                    Fehler_Medium window = new Fehler_Medium();
                    window.setVisible(true);
                    return;
                }
            }

            mdl.add(m);
            ListeSpeichern();

        } else {
            try {
                f.createNewFile();
            } catch (IOException d) {
                System.err.println(d);
            }
            Iterator<Medium> it = mdl.iterator();

            while (it.hasNext()) {
                Medium cmp = it.next();
                if (cmp.getArtikelnr() == m.getArtikelnr()) {
                    Fehler_Medium window = new Fehler_Medium();
                    window.setVisible(true);
                    return;
                }
            }
            mdl.add(m);
            ListeSpeichern();
        }
    }

    /**
     * Das Medium wird anhand der Artikelnummer aus der Medienliste gefiltert
     * und zurückgegeben, wenn es in der Liste vorhanden ist.
     *
     * @param txtArtNr - Artikelnummer des gesuchten Mediums. Sie dient zur
     * Identifikation
     * @param it Lokaler Iterator
     * @param m Medium das zurückgegeben wird. -> Wenn Medium nicht vorhanden,
     * dann wird null returned.
     * @return Gesuchtes Medium
     */
    @Override
    public Medium filtern(int txtArtNr) {
        ListeLaden();

        Iterator<Medium> it = mdl.iterator();

        while (it.hasNext()) {
            Medium m = it.next();
            if (m.getArtikelnr() == txtArtNr) {
                return m;
            }
        }
        return null;
    }

    /**
     * Lies den Inhalt der Datei Medienliste.md in die Medienliste (mdl) ein und
     * gibt diese zurück.
     *
     * @param o - ObjectInputStream - Liest die Datei Medienliste.md aus.
     * @return mdl Liste in die der Dateiinhalt geschrieben wird.
     */
    @Override
    public List getListe() {
        ListeLaden();
        return mdl;
    }

    /**
     * Sucht das zu löschende Medium anhand der Artikelnummer (ArtNr) und löscht
     * nach Auffinden des gesuchten Mediums dieses aus der Liste mdl. Danach
     * wird die aktualisierte Liste zurück in die Datei Medienliste.md
     * geschrieben.
     *
     * @param ArtNr - Die Artikelnummer des zu löschenden Mediums
     * @param Medium n - Lokales Medium in dem das zu löschende Medium
     * zwischengespeichert wird.
     * @param it - Lokaler Iterator für die Liste mdl
     */
    @Override
    public void löschen(int ArtNr) {
        ListeLaden();
        Iterator<Medium> it = mdl.iterator();
        Medium n = null;

        while (it.hasNext()) {
            Medium m = it.next();
            if (m.getArtikelnr() == ArtNr) {
                n = m;
                break;
            }
        }
        mdl.remove(n);
        ListeSpeichern();
    }

    /**
     * Zuständig für das Laden der Medienliste aus der Datei Medienliste.md und
     * speichern deren Inhalt in der lokalen Medienliste mdl. Wurde zu Gunsten
     * der Code-Redundanz in diese Funktion ausgelager.
     *
     * @throws IOException
     * @exception Fehlertrace wird ausgegeben
     * @throws ClassNotFoundException
     * @exception Fehlertrace wird ausgegeben
     */
    public void ListeLaden() {
        try {
            ObjectInput o = new ObjectInputStream(new FileInputStream(f));
            mdl = (List<Medium>) o.readObject();
            o.close();
        } catch (IOException e) {
            System.err.println(e);
        } catch (ClassNotFoundException e) {
            System.err.println(e);
        }
    }

    /**
     * Zuständig für das Schreiben und Speichern der lokalen Medienliste (mdl)
     * in der Datei Medienliste.md Wurde im Zuge der Kapselung in eine eigene
     * Funktion ausgelagert.
     *
     * @throws IOException
     */
    public void ListeSpeichern() {
        try {
            f.delete();
            f.createNewFile();
            ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(f));
            o.writeObject(mdl);
            o.close();
        } catch (IOException e) {
            System.err.println(e);
        }
    }

    
    /**
     * Legt die Datei Medienliste.md neu an und fügt eine leere Medienliste hinzu.
     */
    @Override
    public void DateiErneuern() {
        mdl = new ArrayList<Medium>();
        try {
            f.createNewFile();
            ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(f));
            o.writeObject(mdl);
            o.close();
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}
